# Create your views here.
# -*- coding: UTF-8 -*-
from django.http import *
from django.template import Context, loader
from django.contrib.auth.decorators import login_required
from webtester.netcat.models import *
from django.forms.models import model_to_dict
from django.shortcuts import *
import subprocess

# Wykonuje polecenie użytkownika; polecenie do wykonania
# dostępne jest w sesji pod kluczem 'netcat_command'.
# Obiekt HttpResponse zwraca generator, który iteruje
# po kolejnych liniach przeczytanych ze stardardowego wyjścia.
# Wygenerowana odpowiedź wyświetlana jest w elemencie IFRAME.
@login_required
def process(request):
    cmd = request.session['netcat_command']
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    def process():
        while p.poll() is None:
            l = p.stdout.readline().decode('cp852')
            yield '<pre>'+l+'</pre>'

    return HttpResponse(process())

# Widok który prezentuje odpowiedź wygenerowaną przez polecenie.
@login_required
def executed(request):
    t = loader.get_template('tester/executed.html')
    c = Context({
            'currentTab': 'netcat',
            'command': request.session['netcat_command'],
        })
    
    return HttpResponse(t.render(c))

# Widok główny. W przypadku żądania GET generuje formularz dla użytkownika
# (uwzględniając prawa nadane przez 'superusera'). W przypadku żądania POST
# waliduje dane; w przypadku gdy wprowadzone dane są niepoprawne informacja
# zwrotna z wiadomościami o błędach jest zwracana. Gdy wprowadzone dane są
# prawidłowe i użytkownika ma prawo do przełącznika/opcji, następuje przekierowanie
# do widoku 'executed'.

# TODO: Zabezpieczyć formularz przed wstrzyknięciem:
# a) przełącznika/opcji do której użytkownik nie ma uprawnień,
# b) innego/innych poleceń!

# TODO: Jeden generyczny widok dla wszystkich poleceń.
# TODO: Dodawanie nowych poleceń poprzez dostarczenie pliku
#       konfiguracyjnego dla modelu. Na podstawie pliku
#       konfiguracyjnego generowany jest plik modelu,
#       który działa poprawnie z nowym, bardziej generycznym widokiem.
@login_required
def index(request):
    try:
        permissionsForOptionsCollection = NcPermissionForOption.objects.get(user=request.user.id)
    except NcPermissionForOption.DoesNotExist:
        p = NcPermissionForOption(user=request.user)
        p.save()
        permissionsForOptionsCollection = p

    try:
        permissionsForParametersCollection = NcPermissionForParameter.objects.get(user=request.user.id)
    except NcPermissionForParameter.DoesNotExist:
        p = NcPermissionForParameter(user=request.user)
        p.save()
        permissionsForParametersCollection = p

    if 'netcat_command' in request.session:
        del request.session['netcat_command']

    if request.method == 'POST':
        forOptionsForm = NcFormForOptions(request.POST)
        forParametersForm = NcFormForParameters(request.POST)
        hostForm = HostForm(request.POST)
        if forOptionsForm.is_valid() and forParametersForm.is_valid() and hostForm.is_valid():
            command = []  
            command.append("nc ")
            optionsDct = model_to_dict(permissionsForOptionsCollection, exclude=('id', 'user'))
	    parametersDct = model_to_dict(permissionsForParametersCollection , exclude=('id', 'user'))
            for field in forOptionsForm:
                if forOptionsForm.cleaned_data[field.name] and optionsDct[field.name]:
                    command.append(field.label)

            for field in forParametersForm:
                if forParametersForm.cleaned_data[field.name] and parametersDct[field.name]:
                    command.append(field.label + " " + str(forParametersForm.cleaned_data[field.name]))
	    
	    command.append(" " + hostForm.cleaned_data['host'])
	    request.session['netcat_command'] = ' '.join(command).lower().replace(';','').replace('and','').replace('or','')
            return HttpResponseRedirect('../netcat-executed')
        else:
            return render_to_response('tester/netcat.html', {
                'user': request.user,
                'forOptionsForm': forOptionsForm,
                'forParametersForm' : forParametersForm,
                'hostForm' : hostForm,
                'forOptionsPermissions' : model_to_dict(permissionsForOptionsCollection, exclude=('id', 'user')),
                'forParametersPermissions' : model_to_dict(permissionsForParametersCollection , exclude=('id', 'user')),
            })
    else:
        t = loader.get_template('tester/netcat.html')
                
        c = Context({
            'user': request.user,
            'forOptionsForm' : NcFormForOptions(),
            'forParametersForm' : NcFormForParameters(),
            'hostForm' : HostForm(),
            'forOptionsPermissions' : model_to_dict(permissionsForOptionsCollection, exclude=('id', 'user')),
            'forParametersPermissions' : model_to_dict(permissionsForParametersCollection , exclude=('id', 'user')),
        })

        return HttpResponse(t.render(c))
